package banaanvraag.tools.stackf;

/*
 * Copyright 2013 Banaanvraag.
 *
 * MIT License, details are found in the LICENSE text file
 */



import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.regex.Pattern;

/**
 *
 * @author Wukl
 */
public class StackF {
    
    private HashMap<String, String> entries;
    private List<String> rootGroups;
    
    private Pattern group = Pattern.compile("[\\p{Alnum}\\.]+:");
    private Pattern entry = Pattern.compile("[\\p{Alnum}\\.]+ = .+");
    private Pattern array = Pattern.compile("[\\(\\{](\\p{Alnum}+,)+[\\)\\}]");
    
    private String name;
    
    public StackF(String filename) throws FileNotFoundException, IOException {
        name = filename;
        
        BufferedReader in = new BufferedReader(new FileReader(filename));
        
        String currentLine;
        String groupPrefix;
        String t;
        
        String[] entryParts;
        
        int groupDepth;
        int i;
        
        ArrayList<String> groups = new ArrayList<>();
        
        entries = new HashMap<>();
        rootGroups = new ArrayList<>();
        
        while(in.ready()) {
            currentLine = in.readLine();
            
            
            if(currentLine.startsWith("#")) {
                continue;
            }
            
            groupDepth = countSpaces(currentLine) / 2;
            
            ensureSize(groups, groupDepth + 2);
            
            groupPrefix = "";
            i = 0;
            while(i < groupDepth && i < groups.size()) {
                if(groups.get(i) == null) {
                    i++;
                    continue;
                }
                groupPrefix = groupPrefix.concat(groups.get(i)).concat(".");
                i++;
            }
            
            if(group.matcher(currentLine.trim()).matches()) {
                t = currentLine.trim().substring(0, currentLine.trim().length() - 1);
                groups.set(groupDepth, t);
                if(groupDepth == 0) {
                    rootGroups.add(t);
                }
            }
            else if(entry.matcher(currentLine.trim()).matches()) {
                entryParts = currentLine.trim().split(" = ", 2);
                entries.put(groupPrefix.concat(entryParts[0]), entryParts[1]);
            }
        }
    }
    
    public void write(String filename) throws IOException {
        BufferedWriter out = new BufferedWriter(new FileWriter(filename));
        
        Iterator<String> i = entries.keySet().iterator();
        String currentKey;
        
        while(i.hasNext()) {
            currentKey = i.next();
            out.write(currentKey + " = " + entries.get(currentKey));
        }
        
        out.flush();
        out.close();
    }
    
    public void save() throws IOException {
        write(name);
    }
    
    // <editor-fold desc="Retrieving values">
    
    public String getString(String key) {
        return entries.get(key);
    }
    
    public int getInt(String key) {
        return Integer.parseInt(entries.get(key));
    }
    
    public long getLong(String key) {
        return Long.parseLong(entries.get(key));
    }
    
    public float getFloat(String key) {
        return Float.parseFloat(entries.get(key));
    }
    
    public double getDouble(String key) {
        return Double.parseDouble(entries.get(key));
    }
    
    public boolean getBoolean(String key) {
        return entries.get(key).equalsIgnoreCase("true") 
            || entries.get(key).equalsIgnoreCase("1") 
            || entries.get(key).equalsIgnoreCase("T")
            || entries.get(key).equalsIgnoreCase("yes")
            || entries.get(key).equalsIgnoreCase("y")
            || entries.get(key).equalsIgnoreCase("not no")
            || ((new Random()).nextBoolean()
                && entries.get(key).equals("maybe"));
    }
    
    public String[] getArray(String key) {
        String[] ret;
        if(array.matcher(entries.get(key)).matches()) {
            String ar = entries.get(key).substring(1, entries.get(key).length());
            String[] parts = ar.split(",");
            return parts;
        }
        return null;
    }
    
    // </editor-fold>
    
    public void set(String key, String value) {
        entries.put(key, value);
    }
    
    public Iterator<String> getKeyIterator() {
        return entries.keySet().iterator();
    }
    
    public List<String> getRootGroups() {
        return rootGroups;
    }
    
    private int countSpaces(String str) {
        int i = 0;
        while(i < str.length()) {
            if(str.charAt(i) != ' ') {
                break;
            }
            i++;
        }
        return i;
    }
    
    private void ensureSize(List list, int size) {
        if(list.size() < size) {
            while(list.size() < size) {
                list.add(null);
            }
        }
    }
}
